Skip to content

feat(docs): add hreflang alternate links for localized pages#35

Merged
steipete merged 1 commit into
openclaw:mainfrom
notadev99:seo-hreflang-alternates
Jun 7, 2026
Merged

feat(docs): add hreflang alternate links for localized pages#35
steipete merged 1 commit into
openclaw:mainfrom
notadev99:seo-hreflang-alternates

Conversation

@notadev99

Copy link
Copy Markdown
Contributor

Problem

The docs site renders every page in 19 locales and already emits <link rel="canonical">, per-locale <html lang>, and og:locale — but there are no hreflang / rel="alternate" tags anywhere in the output. Without them, search engines can't associate the localized variants of a page, so the translations compete with the English original as duplicate content instead of being served to the right audience by language/region.

Change

In scripts/docs-site/build.mjs, add a hreflangLinks(page) helper that, for each page, emits one <link rel="alternate" hreflang="…"> per locale that publishes the same slug, plus an x-default pointing at the English version.

  • Self-referential — the page links to itself, per Google's guidance.
  • Reuses existing primitiveslocales, allPageByKey, pageRoute(), and htmlLang() (the same building blocks the language picker already uses).
  • Safe gating — only emitted when a canonical origin is set (same condition as the canonical tag). Hidden/noindex pages, and hidden locale variants, are excluded so alternates never point at non-indexable URLs.
  • Single-locale pages emit nothing (no alternates needed).

Verification

npm run docs:build:shell + npm run docs:smoke:shell pass. Sample output for the en home page:

<link rel="alternate" hreflang="en" href="https://docs.openclaw.ai/">
<link rel="alternate" hreflang="fr" href="https://docs.openclaw.ai/fr">
<link rel="alternate" hreflang="de" href="https://docs.openclaw.ai/de">
… (19 locales) …
<link rel="alternate" hreflang="x-default" href="https://docs.openclaw.ai/">

Localized pages cross-link back to English, e.g. it/channels emits hreflang="en" → /channels and x-default → /channels. A noindex page emits zero alternates.

Added smoke.mjs assertions covering the en home page (self + x-default) and the it/channels page (cross-link back to English).

Every page is rendered in 19 locales and emits canonical + og:locale, but
no hreflang alternates exist, so search engines can't associate the locale
variants and they compete as duplicate content.

Emit <link rel="alternate" hreflang="..."> for each locale that publishes
the same slug, plus an x-default pointing at the English version. Tags are
self-referential and gated on a canonical origin; hidden/noindex pages and
hidden locale variants are excluded.

Adds smoke checks for the en home page (self + x-default) and the it/channels
page (cross-link back to English).
@notadev99 notadev99 requested a review from a team as a code owner June 6, 2026 16:56
@steipete steipete merged commit 6f8c6d6 into openclaw:main Jun 7, 2026
4 checks passed
@steipete

steipete commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Landed in 6f8c6d6.

Tested before merge:

  • make docs-check
    • built 23,123 pages in dist/docs-site
    • built docs search index: 682 entries, 3523 KiB
    • Pagefind indexed 11,884 pages across 19 languages
    • R2 prep completed: 50,351 objects
    • docs smoke passed: shell, routing, skin, and hidden fixture checks passed in full mode
  • /Users/steipete/Projects/agent-scripts/skills/autoreview/scripts/autoreview --mode branch --base origin/main --prompt "Review PR #35 hreflang alternate links. Tests passed locally: make docs-check. Focus on correctness of generated hreflang/canonical behavior, hidden pages, locale routes, and escaping."
    • clean: no accepted/actionable findings

GitHub checks on the PR head were green before merge: Docs Code CI and CodeQL.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants